package code.google.jcustomize;

import javax.servlet.jsp.el.ELException;
import javax.servlet.jsp.el.ExpressionEvaluator;
import javax.servlet.jsp.el.FunctionMapper;
import javax.servlet.jsp.el.VariableResolver;

import org.w3c.dom.Element;
import org.w3c.dom.Node;

abstract class AbstractAction {
    private final static String ACTION_CLASS_PREFIX = "";
    private final static String ACTION_CLASS_SUFFIX = "Action";
    private String condition;
    private boolean required;
    
    void parse(Element action) {
        String _required = action.getAttribute("required");
        required = "true".equalsIgnoreCase(_required) || "yes".equalsIgnoreCase(_required);
        condition = action.getAttribute("if");
        if (condition.length() == 0) condition = null;
    }
    
    abstract boolean perform(ConfigSource cs, ExpressionEvaluator ee, VariableResolver vr, FunctionMapper fm);
    
    boolean skip(ConfigSource cs, ExpressionEvaluator ee, VariableResolver vr, FunctionMapper fm) {
        if (condition == null || condition.indexOf("${") < 0)
            return false;
        try {
            Boolean result = (Boolean)ee.evaluate(condition, Boolean.class, vr, fm);
            return result.booleanValue();
        } catch (ELException e) {
            e.printStackTrace();
            return false;
        }
    }
    
    public static AbstractAction read(Node n) {
        if (n == null || n.getNodeType() != Node.ELEMENT_NODE)
            return null;
        
        Element actionEl = (Element)n;
        String actionName = actionEl.getLocalName().toLowerCase();
        String actionClassPackage = AbstractConfig.class.getPackage().getName();
        String actionClassName = ACTION_CLASS_PREFIX + Character.toUpperCase(actionName.charAt(0)) + actionName.substring(1) + ACTION_CLASS_SUFFIX;
        
        try {
            Class actionClass = Class.forName(actionClassPackage + "." + actionClassName);
            AbstractAction aa = (AbstractAction)actionClass.newInstance();
            aa.parse(actionEl);
            return aa;
        } catch (ClassNotFoundException cnfe) {
            System.err.println(cnfe.getMessage());
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }
}
